package learning.pcfg.model;

import java.util.ArrayList;
import java.util.List;

public class MNFTransformer {

	/*
	 * Transforms a grammar into MNF.
	 */
	public static Grammar transform(Grammar grammar) {
		
		List<InnerProduction> mnfProds = new ArrayList<InnerProduction>();
		for (InnerProduction ip : grammar.innerProductions) {
			for (InnerProduction tip : transformProduction(ip))			
				mnfProds.add(tip);			
		}		
		return new Grammar(grammar.terminalProductions, mnfProds);
	}
	
	private static List<InnerProduction> transformProduction(InnerProduction ip) {
		List<InnerProduction> mnfProds = new ArrayList<InnerProduction>();
		
		if (ip.rhs.length <= 2) {
			mnfProds.add(ip);
			return mnfProds;
		}
		
		for (int i=0; i < ip.rhs.length - 1; i++) {
			
			String lhs = (i > 0) ? ip.lhs + "_" + i : ip.lhs;
			
			String[] rhs = new String[2];
			rhs[0] = ip.rhs[i];			
			rhs[1] = (i < ip.rhs.length - 2)? ip.lhs + "_" + (i+1) : ip.rhs[i];
			
			if (i == 0)
				// only the first prod is learnable
				mnfProds.add(new InnerProduction(ip.group, lhs, rhs, true));
			else
				mnfProds.add(new InnerProduction(ip.group, lhs, rhs, false));
		}
		return mnfProds;
	}	
}